package test.demo;

import tech.waterism.modelbase.PredictBase;
import tech.waterism.modelbase.PredictResult;
import com.alibaba.fastjson.JSON;
import lombok.SneakyThrows;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * topmodel模型
 *
 * @author 初京刚
 * @version 1.0
 * @date 2022-1-7
 */
public class TOPE extends PredictBase {

    /**
     * 时段数
     */
    private int nstep;

    /**
     * 步长，小时
     */
    private int dt;

    /**
     * 雨强，米/小时
     */
    private double[] rain;

    /**
     * 潜在蒸散发，米/小时
     */
    private double[] pe;

    /**
     * 实测泄流，米/小时
     */
    private double[] Qobs;

    /**
     * 地形指数直方图值的数量
     */
    private int num_topodex_values;

    /**
     * 集水区面积占整个集水区的百分比，%，默认为1
     */
    private double area;

    /**
     * 对应地形指数的面积分布，%，总和为1
     */
    private double[] dist_area_lnaotb;

    /**
     * 地形指数
     */
    private double[] lnaotb;

    /**
     * 河道数
     */
    private int num_channels;

    /**
     * 针对距离，河道面积的累积分布，%，总和为1
     */
    private double[] cum_dist_area_with_dist;

    /**
     * 从出口到已知面积的河道上点的距离
     */
    private double[] dist_from_outlet;

    /**
     * 非饱和区最大蓄水深度（m），指蓄水缺陷增加时导水率下降的指数缩放参数，是一个深度单位的变量，不需率定
     */
    private double szm;

    /**
     * 土壤饱和导水率（m/h），指当土壤刚好饱和到表面时的导水率，率定
     */
    private double t0;

    /**
     * 重力排水的时间滞时参数（h），非饱和区每单位蓄水缺陷的时间延迟，率定
     */
    private double td;

    /**
     * 每单位面积的初始地下水流量，m/h
     */
    private double Q0;

    /**
     * 根系区初始缺水量（m），低于田间持水量
     */
    private double sr0;

    /**
     * k+ND ~ k+ND+IR (IR = 0,1,……,NR-ND) 时段到达出口断面的径流比例 (k为降雨时段)
     */
    double[] ARate;
    /**
     * k+ND ~ k+ND+IR (IR = 0,1,……,NR-ND) 时段内到达出口断面的径流比例 (k为降雨时段)
     */
    double[] ARateData;
    /**
     * 根系区点土壤缺水量初值（m）
     */
    private double[] sr0Initial;
    /**
     * 初始总壤中流（m3/s）
     */
    private double qb0Initial;
    /**
     * 时段平均地下水位（m）
     */
    private double[] SBAR;
    /**
     * 初始时段总壤中流（m）
     */
    private double qb0DTInitial;
    /**
     * 非饱和层点土壤含水量（m）
     */
    private double[] su0Initial;
    /**
     * 非饱和区最大蓄水深度（m）
     *//*
    private double szm;
    *//**
     * 土壤饱和导水率（m2/h）
     *//*
    private double t0;*/
    /**
     * 土壤时段饱和输水量（m2）
     */
    private double T0DT;
    /**
     * 根系区最大蓄水容量/田间持水量（m），可率定
     */
    private double srMax;
    /**
     * 重力排水的时间滞时参数（h/m）
     *//*
    private double td;*/
    /**
     * 采用GREEN-AMPT计算入渗标志
     */
    private int infex;
    /**
     * 土壤表征饱和导水率(m/h)，表层土壤水力传导率，可率定
     */
    private double xk0;
    /**
     * GREEN-AMPT方法的湿润锋面吸力(m)，可率定
     */
    private double hf;
    /**
     * 土壤孔隙度变化，GREEN-AMPT方法的湿润锋面含水量变化，可率定
     */
    private double dth;
    /**
     * 时段湿润锋面吸力(m)
     */
    private double cd;
    /**
     * 主河道汇流有效速度（m/h），河道平均流速，不率定
     */
    private double chv;
    /**
     * 地表坡面汇流有效速度（m/h），不率定
     */
    private double rv;
    /**
     * 地表坡面时段汇流（m）
     */
    private double RVDT;
    /**
     * 主河道时段汇流（m）
     */
    private double CHVDT;
    /**
     * 流域面积（km2）
     */
    private double Area;
    /**
     * 地形指数累积面积（无量纲）
     */
    private double tArea;
    /**
     * 主河道河长（m）
     */
    private double length;
    /**
     * 主河道分级
     */
    private int NCH;
    /**
     * 分级河道到出口断面的最远距离（m）
     */
    private double[] D;
    /**
     * 分级河道的累积流域面积（km2）
     */
    private double[] ACH;
    /**
     * 到出口断面分级河道最远距离对应的径流滞后时段
     */
    private double[] TCH;
    /**
     * 分级河道最远点坡面汇流以及河道汇流时段
     */
    private int NR;
    /**
     * 分级河道最近点河道汇流时段
     */
    private int ND;
    /**
     * 分级河道最远点坡面汇流时段
     */
    private int NRD;
    /**
     * 初始各汇流时段总壤中流出口断面汇流（m）
     */
    private double[] qb0DTInitials;
    /**
     * 初始各时段总壤中流（m）
     */
    private double[] rb0Initials;
    /**
     * 地形指数（从大到小排列）
     */
    private double[] st;

    /**
     * 大于该位置对应地形指数并小于前一位置对应地形指数的累积面积（无量纲）
     */
    private double[] ac;

    /**
     * 大于该位置对应地形指数并小于前一位置对应地形指数的累积面积占地形指数累积面积比例
     */
    private double[] AC;

    /**
     * 地形指数种类
     */
    private int NAC;

    /**
     * 地形指数面积积分
     */
    private double TL;

    /**
     * 缺水量为零时的时段壤中流（m）
     */
    private double SZQ;

    /**
     * 流域 月蒸发量（mm）
     */
    private double[] ES;

    /**
     * 流域 时段蒸发量（mm）
     */
    private double[] floodE;

    /**
     * 降水时间
     */
    private Date[] floodTm;

    /**
     * 降水量
     */
    private double[] floodDrp;

    /**
     * 降水序列长度
     */
    private Integer floodRainRange;

    /**
     * 降水时段长
     */
    private double timeInterval;

    /**
     * 模拟总产流
     */
    private double[] RunoffSim;

    /**
     * 模拟非饱和区总下渗，Qv表示土壤非饱和区中的水分垂直进入饱和地下水带的下渗率
     */
    private double[] QUZ;

    /**
     * 坡面流-径流
     */
    private double[] RS;

    /**
     * 壤中流-径流
     */
    private double[] RB;

    /**
     * 坡面流-流量，饱和坡面流
     */
    private double[] QS;

    /**
     * 壤中流-流量
     */
    private double[] QB;

    /**
     * 出口断面流量，流域总径流，Qb与Qs之和
     */
    private double[] Q;

    /**
     * 根系区点各时段缺水量（m） srz表示植被根系区
     */
    private double[][] Srz0;

    /**
     * 非饱和层点各时段含水量（m） srz表示土壤非饱和区
     */
    private double[][] Suz0;

    /**
     * 饱和地下水面点时段距地表深度（非饱和层土壤蓄水能力）（m）、z表示饱和地下水水面距流域土壤表面的深度（缺水深）
     */

    private double[][] SD;

    public TOPE(Map<String, String> data) {
        super();
        //        sr0Initial = JSON.parseObject(data.get("SR0"), double[].class);
        //        qb0Initial = Double.parseDouble(data.get("QB0"));
        //        su0Initial = JSON.parseObject(data.get("SU0"), double[].class);

        szm = Double.parseDouble(data.get("SZM"));
        t0 = Double.parseDouble(data.get("T0"));
        srMax = Double.parseDouble(data.get("SRMAX"));
        td = Double.parseDouble(data.get("TD"));
        infex = Integer.parseInt(data.get("INFEX"));
        xk0 = Double.parseDouble(data.get("XK0"));
        hf = Double.parseDouble(data.get("HF"));
        dth = Double.parseDouble(data.get("DTH"));
        chv = Double.parseDouble(data.get("CHV"));
        rv = Double.parseDouble(data.get("RV"));
        Area = Double.parseDouble(data.get("F"));
        length = Double.parseDouble(data.get("L")) * 1000;
        NCH = Integer.parseInt(data.get("N"));

        st = JSON.parseObject(data.get("ST"), double[].class);
        ac = JSON.parseObject(data.get("AC"), double[].class);
        NAC = ac.length;
        D = JSON.parseObject(data.get("D"), double[].class);
        for (int i = 0; i < D.length; i++) {
            D[i] *= 1000;
        }
        ACH = JSON.parseObject(data.get("ACH"), double[].class);
        ES = JSON.parseObject(data.get("ES"), double[].class);
        floodTm = JSON.parseObject(data.get("dt"), Date[].class);             // input[i].data.dt
        floodDrp = JSON.parseObject(data.get("rain"), double[].class);        // input[i].data.rain
        floodE = JSON.parseObject(data.get("evaporation"), double[].class);  // input[i].data.evaporation
        floodRainRange = floodDrp.length;
        if (floodTm.length > 1) {
            timeInterval = getHours(floodTm[0], floodTm[1]);
        } else {
            timeInterval = Double.parseDouble(data.get("clen"));                  // index.clen
        }

        RunoffSim = new double[floodRainRange];
        QUZ = new double[floodRainRange];
        RS = new double[floodRainRange];
        RB = new double[floodRainRange];
        rb0Initials = new double[floodRainRange + 1];
        QS = new double[floodRainRange];
        QB = new double[floodRainRange];
        Q = new double[floodRainRange];
        Srz0 = new double[floodRainRange + 1][NAC];
        Suz0 = new double[floodRainRange + 1][NAC];
        SD = new double[floodRainRange][NAC];

        sr0Initial = new double[NAC];
        qb0Initial = Double.parseDouble(data.get("QB0"));
        su0Initial = new double[NAC];
        int I;
        for (I = 0; I < NAC; I++) {
            if (I > JSON.parseObject(data.get("SR0"), double[].class).length - 1) {
                sr0Initial[I] = 0.0;
            } else {
                sr0Initial[I] = JSON.parseObject(data.get("SR0"), double[].class)[I];
            }
            if (I > JSON.parseObject(data.get("SU0"), double[].class).length - 1) {
                su0Initial[I] = 0.0;
            } else {
                su0Initial[I] = JSON.parseObject(data.get("SU0"), double[].class)[I];
            }
        }
    }

    /**
     * 构造方法，获取topmodel模型构造数据
     *
     * @param paramFloodDrp     降水量
     * @param paramFloodTm      降水时间
     * @param paramTimeInterval 降水时段长
     * @param paramSr0Initial   根系区土壤饱和缺水量初值
     * @param paramQb0Initial   初始壤中流
     * @param paramSzm          非饱和区最大蓄水深度（m）
     * @param paramT0           饱和导水率
     * @param paramSrMax        根系区最大蓄水容量（m）
     * @param paramTd           滞时系数
     * @param paramChv          地表坡面汇流有效速度（m/h）
     * @param paramRv           地表坡面汇流有效速度（m/h）
     * @param paramSt           地形指数
     * @param paramAc           地形指数对应面积占流域面积的比例
     * @param paramES           流域 日潜在蒸发量（mm）
     * @param paramArea         流域面积（km2）
     * @param paramLength       主河道河长（m）
     * @param paramSection      主河道分级
     */

    public TOPE(double[] paramFloodDrp, Date[] paramFloodTm, double paramTimeInterval, double[] paramSr0Initial,
                double paramQb0Initial, double paramSzm, double paramT0, double paramSrMax, double paramTd,
                double paramChv, double paramRv, double[] paramSt, double[] paramAc, double[] paramES, double paramArea,
                double paramLength, int paramSection) {
        super();
        sr0Initial = paramSr0Initial;
        qb0Initial = paramQb0Initial;
        szm = paramSzm;
        t0 = paramT0;
        srMax = paramSrMax;
        td = paramTd;
        chv = paramChv;
        rv = paramRv;
        st = paramSt;
        ac = paramAc;
        ES = paramES;

        Area = paramArea;
        length = paramLength;
        NCH = paramSection;

        floodTm = paramFloodTm;
        floodDrp = paramFloodDrp;
        floodRainRange = floodDrp.length;
        timeInterval = paramTimeInterval;
        RunoffSim = new double[floodRainRange];
        RS = new double[floodRainRange];
        RB = new double[floodRainRange];
        QS = new double[floodRainRange];
        QB = new double[floodRainRange];
    }

    /**
     * 构造方法，获取topmodel模型构造数据
     *
     * @param paramSzm     非饱和区最大蓄水深度（m）
     * @param paramT0      饱和导水率
     * @param paramSrMax   根系区最大蓄水容量（m）
     * @param paramTd      滞时系数
     * @param paramChv     地表坡面汇流有效速度（m/h）
     * @param paramRv      地表坡面汇流有效速度（m/h）
     * @param paramSt      地形指数
     * @param paramAc      地形指数对应面积占流域面积的比例
     * @param paramES      流域 日潜在蒸发量（mm）
     * @param paramArea    流域面积（km2）
     * @param paramLength  主河道河长（m）
     * @param paramSection 主河道分级
     */

    public TOPE(double paramSzm, double paramT0, double paramSrMax, double paramTd, double paramChv, double paramRv,
                double[] paramSt, double[] paramAc, double[] paramES, double paramArea, double paramLength,
                int paramSection) {
        super();
        szm = paramSzm;
        t0 = paramT0;
        srMax = paramSrMax;
        td = paramTd;
        chv = paramChv;
        rv = paramRv;
        st = paramSt;
        ac = paramAc;
        ES = paramES;

        Area = paramArea;
        length = paramLength;
        NCH = paramSection;
    }

    public double[] getFloodDrp() {
        return floodDrp;
    }

    /**
     * @param paramFloodDrp 降水量
     */

    public void setFloodDrp(double[] paramFloodDrp) {
        this.floodDrp = paramFloodDrp;
        floodRainRange = floodDrp.length;
        RunoffSim = new double[floodRainRange];
        RS = new double[floodRainRange];
        RB = new double[floodRainRange];
        QS = new double[floodRainRange];
        QB = new double[floodRainRange];
    }

    public Date[] getFloodTm() {
        return floodTm;
    }

    /**
     * @param paramFloodTm 降水时间
     */

    public void setFloodTm(Date[] paramFloodTm) {
        this.floodTm = paramFloodTm;
    }

    public double getTimeInterval() {
        return timeInterval;
    }

    /**
     * @param paramTimeInterval 降水时段长
     */

    public void setTimeInterval(double paramTimeInterval) {
        this.timeInterval = paramTimeInterval;
    }

    public double[] getSr0Initial() {
        return sr0Initial;
    }

    public void setSr0Initial(double[] sr0Initial) {
        this.sr0Initial = sr0Initial;
    }

    public double getQb0Initial() {
        return qb0Initial;
    }

    public void setQb0Initial(double qb0Initial) {
        this.qb0Initial = qb0Initial;
    }

    /**
     * 模型计算
     */

    public Map<String, double[]> TOPMODEL() throws Exception {

        // 产流初始化
        init_runoff();

        // 产流计算
        topmodel_runoff();

        // 汇流初始化
        init_flow();

        // 汇流计算
        topmodel_flow();

        Map<String, double[]> simulationResult = new HashMap<>();

        simulationResult.put("RunoffSim", RunoffSim);
        simulationResult.put("RS", RS);
        simulationResult.put("RB", RB);
        simulationResult.put("QS", QS);
        simulationResult.put("QB", QB);
        simulationResult.put("QSim", Q);

        return simulationResult;
    }

    /**
     * 计算地形指数面积积分、缺水量为零时的时段壤中流、流域初始平均水位
     */
    private void init_runoff() {
        AC = new double[NAC];
        SBAR = new double[floodRainRange + 1];
        tArea = ac[0];
        for (int i = 1; i < NAC; i++) {
            tArea = tArea + ac[i];
        }

        /*a/tanB values should be ordered from high to low with ST(1)
        as an upper limit such that AC(1) should be zero, with AC(2) representing
        the area between ST(1) and ST(2)*/
        /*地形指数值从大到小排列，st[0]为上限，ac[0]或AC[0]分别为地形指数大于st[0]的累计面积或大于st[0]的累计面积占地形指数累计面积比例
        ac[i]或AC[i](i=1,...NAC-1)分别为地形指数大于st[i]且小于st[i-1]的累计面积或大于st[i]且小于st[i-1]的累计面积占地形指数累计面积比例
        */
        AC[0] = ac[0] / tArea;
        TL = 0.0;
        for (int i = 1; i < NAC; i++) {
            AC[i] = ac[i] / tArea;
            TL = TL + AC[i] * (st[i] + st[i - 1]) / 2;
        }

        /*Convert parameters to m/time step DT*/
        if(qb0Initial <= 0) {
            qb0Initial = 4.5E-5;
        }
        qb0DTInitial = qb0Initial * timeInterval * 3600 / (Area * 1000000);
        rb0Initials[0] = qb0Initial;

        /*《分布式流域水文模型》P85公式4-17中Q0的计算，单位为m3/s，由于SZQ单位为m，需消掉面积A以将Q0转换单位成m并得出SZQ*/
        T0DT = t0 * timeInterval;
        SZQ = T0DT * Math.exp(-TL);
        /*《分布式流域水文模型》P85公式4-20，计算初始平均地下水位*/
        SBAR[0] = (-1) * szm * Math.log(qb0DTInitial / SZQ);
    }

    /**
     * 产流计算
     *
     * @return 净雨过程
     */
    private void topmodel_runoff() throws Exception {

        double sr0InitialAverage = 0.0, su0InitialAverage = 0.0;//根系区与非饱和区土壤平均缺水量初值
        for (int i = 1; i < sr0Initial.length; i++) {
            sr0InitialAverage = sr0InitialAverage + 0.5 * (sr0Initial[i - 1] + sr0Initial[i]) * AC[i];
            su0InitialAverage = su0InitialAverage + 0.5 * (su0Initial[i - 1] + su0Initial[i]) * AC[i];
        }

        /*根系区点缺水量、非饱和层点含水量赋初值*/
        for (int i = 0; i < NAC; i++) {
            Srz0[0][i] = sr0Initial[i];
            Suz0[0][i] = su0Initial[i];
        }

        double BAL = -SBAR[0] - sr0InitialAverage + su0InitialAverage;// 平衡分析、水量平衡检测

        int IROF = 0; // 积水标志
        double REX = 0.0; // 超渗产流
        double CUMF = 0.0; // 累计下渗量
        //        double ACF = 0.0; //相邻地形指数对应的累积流域面积
        double[] UZ; //非饱和区点下渗量
        double[] EA; //根系区点实际蒸发量

        /*点地表产流深度 = 非饱和区点蓄水深度-点地下水面深度（大于地下水面深度表明产生地表径流）*/
        double[] EX;
        double[] OF;//地表径流

        double SUMP = 0.0; // 降雨求和
        double SUMAE = 0.0; // 蒸发求和
        double SUMQ = 0.0; // 产流求和
        double SUMRZ = 0.0; //根系区缺水量求和
        double SUMUZ = 0.0; //非饱和层含水量求和

        double EPt; // 蒸散发能力（实测蒸发，即ES[]或时段，m）
        double Pt; // 时段降雨（m）
        double RINT; // 时段降雨强度（m/h）
        Map<String, Double> EXPResult;//时段渗透量 m、累计下渗量 m
        double DF; // 时段渗透量（m)

        for (int IT = 0; IT < floodRainRange; IT++) { // floodRainRange为降雨时段数
            QUZ[IT] = 0.0;
            RS[IT] = 0.0;
            RB[IT] = 0.0;
            RunoffSim[IT] = 0.0;

            Pt = floodDrp[IT] / 1000; // 单位转换
            UZ = new double[NAC];
            EX = new double[NAC];
            EA = new double[NAC];
            OF = new double[NAC];

            // 蒸发能力计算
            if (floodE == null || floodE.length != floodRainRange) {
                EPt = calcEvaporationPotential(floodTm[IT], timeInterval) / 1000;
            } else {
                EPt = floodE[IT] / 1000;
            }

            SUMP = SUMP + Pt;

            if (infex == 1) {
                if (Pt > 0) {
                    RINT = Pt / timeInterval;
                    /* GREEN-AMPT INFILTRATION IN A SOIL WITH CONDUCTIVITY DECLINING
                     EXPONENTIALLY WITH DEPTH，参考C语言与Fortran代码版本*/
                    /*理论基础：文献《Infiltration into a class of vertically nonuniform soils》（KEITH BEVEN）*/
                    EXPResult = EXPINF(IROF, IT, RINT, CUMF);
                    DF = EXPResult.get("df");
                    REX = Pt - DF;
                    Pt = Pt - REX;
                } else {
                    REX = 0.0;
                    IROF = 0;
                    CUMF = 0.0;
                }
            }
            /*P IS RAINFALL AVAILABLE FOR INFILTRATION AFTER SURFACE CONTROL CALCULATION*/
            for (int IA = 0; IA < NAC; IA++) {
                /*ACF为相邻两个地形指数区间累计面积的平均值，无特殊意义，本代码版本舍去，统一用对应区间累计面积代替*/
                //                ACF = 0.5 * (AC[IA] + AC[IA+1]);

                UZ[IA] = 0.0;
                EX[IA] = 0.0;
                EA[IA] = 0.0;
                OF[IA] = 0.0;

                /*  饱和地下水表面深度（非饱和层土壤蓄水能力）计算 */
                /*  《分布式流域水文模型》P84公式4-13计算各类型地形指数下的点非饱和区深度即地下水位*/
                SD[IT][IA] = SBAR[IT] + szm * (TL - st[IA]);
                if (SD[IT][IA] < 0.0) {
                    SD[IT][IA] = 0.0;
                }

                /*非饱和层水分运动（垂向）*/

                /*  根系区计算 */
                /* 降雨首先进入根系区，根系区缺水量=根系区缺水量-降雨，如果正值，还缺水，根系区没满；如果负值，多出的部分下渗到非饱和区*/
                Srz0[IT][IA] = Srz0[IT][IA] - Pt;
                if (Srz0[IT][IA] < 0.0) {
                    Suz0[IT][IA] = Suz0[IT][IA] - Srz0[IT][IA];
                    Srz0[IT][IA] = 0.0;
                }

                /*  非饱和层计算 */
                /* 如果非饱和区蓄水量大于饱和地下水表面深度，那么产生地表径流*/
                if (Suz0[IT][IA] > SD[IT][IA]) {
                    EX[IA] = Suz0[IT][IA] - SD[IT][IA];
                    Suz0[IT][IA] = SD[IT][IA];
                }

                /*  非饱和层排水（下渗）UZ计算 */
                if (SD[IT][IA] > 0) {
                    /*《分布式流域水文模型》P83公式4-3计算非饱和区点下渗率，其中td为重力排水的时间滞时参数，单位为h/m，为计算时段下渗量UZ，需将公式4-3乘以timeInterval，
                    即将Fortran代码版本268行最后一个‘）’移到TD后*/
                    UZ[IA] = Suz0[IT][IA] / (SD[IT][IA] * td) * timeInterval;
                    if (UZ[IA] > Suz0[IT][IA]) {
                        UZ[IA] = Suz0[IT][IA];
                    }
                    Suz0[IT][IA] = Suz0[IT][IA] - UZ[IA];
                    if (Suz0[IT][IA] < 0.0000001) {
                        Suz0[IT][IA] = 0.0;
                    }
                    /*《分布式流域水文模型》P85公式4-4，计算整个流域总下渗*/
                    if (IA > 0) {
                        QUZ[IT] = QUZ[IT] + 0.5 * (UZ[IA - 1] + UZ[IA]) * AC[IA];
                    }
                }

                /*依据根系区缺水量计算蒸散量*/
                if (EPt > 0) {
                    /*《分布式流域水文模型》P83公式4-2计算点根系区实际蒸发量*/
                    EA[IA] = EPt * (1 - Srz0[IT][IA] / srMax);
                    if (EA[IA] > (srMax - Srz0[IT][IA])) {
                        EA[IA] = srMax - Srz0[IT][IA];
                    }
                    Srz0[IT][IA] = Srz0[IT][IA] + EA[IA];
                }

                if (IA > 0) {
                    SUMAE = SUMAE + 0.5 * (EA[IA - 1] + EA[IA]) * AC[IA];
                    SUMRZ = SUMRZ + 0.5 * (Srz0[IT][IA - 1] + Srz0[IT][IA]) * AC[IA];
                }

                /* CALCULATION OF FLOW FROM FULLY SATURATED AREA
                  This section assumes that a/tanB values are ordered from high to low*/
                if (IA > 0) {
                    OF[IA] = 0.5 * (EX[IA - 1] + EX[IA]) * AC[IA];
                }
                RS[IT] = RS[IT] + OF[IA];

                /*根系区点缺水量、非饱和层点含水量更新*/
                Srz0[IT + 1][IA] = Srz0[IT][IA];
                Suz0[IT + 1][IA] = Suz0[IT][IA];
            }
            /*ADD INFILTRATION EXCESS*/
            RS[IT] = RS[IT] + REX;

            /* 饱和层水分运动（壤中流）*/
            /*《分布式流域水文模型》P85公式4-17计算壤中流*/
            RB[IT] = SZQ * Math.exp((-1) * SBAR[IT] / szm);
            /*《分布式流域水文模型》P85公式4-19，流域平均地下水位更新*/
            SBAR[IT + 1] = SBAR[IT] - QUZ[IT] + RB[IT];

            rb0Initials[IT + 1] = RB[IT] * (Area * 1000000) / timeInterval;

            RunoffSim[IT] = RS[IT] + RB[IT];
            SUMQ = SUMQ + RunoffSim[IT];
        }
        for (int IA = 1; IA < NAC; IA++) {
            SUMUZ = SUMUZ + 0.5 * (Suz0[floodRainRange - 1][IA - 1] + Suz0[floodRainRange - 1][IA]) * AC[IA];
        }

        BAL = BAL + SBAR[floodRainRange] + SUMP - SUMAE - SUMQ + SUMRZ - SUMUZ;
    }

    /**
     * @param irof 积水标志
     * @param it   时段数
     * @param rint 时段降雨强度 m/h
     * @param cumf 时段初累计下渗 m
     * @return 时段渗透量 m
     * 累计下渗量 m
     */
    private Map<String, Double> EXPINF(int irof, int it, double rint, double cumf) throws Exception {

        cd = hf * dth;
        double SZF = 1. / szm; //f*
        double XKF = xk0;
        double f1 = 0.0, f2 = 0.0, f = 0.0;//湿润锋面深度(累计下渗量)
        double r2;//下渗率
        double tp = 0.0;//表面达到饱和所需时间（积水开始时间）
        double df = 0.0;//时段下渗
        double e = 0.00001;

        Map<String, Double> EXPResult = new HashMap<>();

        double CONST = 0.0; //定积分常数
        double FAC = 1.0; //阶乘
        double fc = 0.0;
        double add = 0.0, sum = 0.0; //求和

        double func = 0.0; //t与时段末之间的小时数，-(t-tp)+((it + 1) * timeInterval-tp)=(it + 1) * timeInterval-t，目的是t趋近于(it + 1) *
        // timeInterval、func趋近于0
        double dfunc = 0.0; //tp到(it + 1) * timeInterval区间的下渗率(积水后的下渗率)

        if (irof != 1) {
            //没发生积水
            if (cumf > 0.0) {
                //有下渗，若要发生积水，初步估计积水时间
                f1 = cumf;
                r2 = -XKF * SZF * (cd + f1) / (1.0 - Math.exp(SZF * f1));
                if (r2 < rint) {
                    //超渗产流，时段起始时刻开始积水
                    tp = (double) it * timeInterval;
                    irof = 1;
                    f = cumf;
                }
            }
            if (irof != 1) {
                //没下渗或没超渗产流
                /*
                理论基础：下渗能力小于降雨强度时，下渗的同时发生超渗产流，随着下渗的进行，累计下渗量逐渐增大，下渗能力逐渐减少。
                数学算法：（1）利用r2与f的反比关系（r越大，f越小），逐步调整累计下渗量，使得下渗率逐步逼近rint（降雨强度），求得对应的累计下渗量。
                            下渗量调整方向一：下渗能力大于rint（降雨强度），增大累计下渗量，减小下渗能力；
                            下渗量调整方向二：下渗能力小于rint（降雨强度），减少累计下渗量，增大下渗能力。
                        （2）利用下渗能力（逼近rint（降雨强度））以及对应的累计下渗量，确定tp（初始值）。
               */
                f2 = cumf + rint * timeInterval;
                r2 = -XKF * SZF * (cd + f2) / (1.0 - Math.exp(SZF * f2));
                if (Math.abs(f2) < 1.0e-09 || r2 > rint) {
                    //时段内没产生积水
                    irof = 0;
                    df = rint * timeInterval;
                    cumf += df;
                    EXPResult.put("df", df);
                    EXPResult.put("cumf", cumf);
                    return EXPResult;
                }
                //时段内产生积水
                f = cumf + r2 * timeInterval;
                for (int i = 1; i <= 20; i++) {
                    r2 = -XKF * SZF * (cd + f) / (1.0 - Math.exp(SZF * f));
                    if (r2 > rint) {
                        f1 = f;
                        f = (f2 + f) * 0.5;
                        if (Math.abs(f - f1) < e)
                            break;
                    } else {
                        f2 = f;
                        f = (f1 + f) * 0.5;
                        if (Math.abs(f - f2) < e)
                            break;
                    }
                    if (i == 20) {
                        System.out.println("Max number of iterations exceeded\n");
//                        throw new Exception("Max number of iterations exceeded");
                    }
                }
                tp = (double) it * timeInterval + (f - cumf) / rint;
            }

            if (tp <= (double) (it + 1) * timeInterval) {
                /* SET UP DEFINITE INTEGRAL CONSTANT USING FPC */
                fc = f + cd;
                for (int j = 1; j <= 10; j++) {
                    FAC = FAC * (double) j;
                    add = Math.pow((fc * SZF), (double) j) / ((double) j * FAC);
                    CONST = CONST + add;
                }
                CONST = Math.log(fc) - (Math.log(fc) + CONST) / Math.exp(SZF * cd);
                irof = 1;
                f = f + 0.5 * rint * ((double) (it + 1) * timeInterval - tp); //为补足一个时段，按照下降规律补上一定的下渗量
            }
        }
        /*
            理论基础：补足一个时段的过度下渗计算
            数学基础：牛顿迭代法求f
                    设r是f(x)的根，选取x0作为r的初始近似值，过点(x0,f(x0))做曲线y=f(x)的切线L，L:y=f(x0)+f'(x0)(x-x0)，则L与x轴交点的横坐标x1=x0-f(x0)
                    /f'(x0)，
                    称x1为r的一次近似值。过点(x1,f(x1))做曲线y=f(x)的切线，并求该切线与x轴交点的横坐标x2=x1-f(x1)/f'(x1)，称x2为r的二次近似值。重复以上过程，
                    得r的近似值序列，其中， xn+1=xn-f(xn)/f'(xn)称为r的n+1次近似值，上式称为牛顿迭代公式。
               */
        if (tp <= (double) (it + 1) * timeInterval) {
            for (int i = 1; i <= 20; i++) {
                fc = f + cd;
                FAC = 1.0;
                for (int j = 1; j <= 10; j++) {
                    FAC = FAC * (double) j;
                    add = Math.pow((fc * SZF), (double) j) / ((double) j * FAC);
                    sum += add;
                }
                func = -(Math.log(fc) - (Math.log(fc) + sum) / Math.exp(SZF * cd) - CONST) / (XKF * SZF) +
                        ((double) (it + 1) * timeInterval - tp);
                //源代码“func=-(log(fc)-(log(fc)+sum)/exp(szf*cd)-constant)/(xkf*szf)-((double)it*dt-tp);”中存在错误，第二项应为“+”
                //目的是func逐渐逼近0
                dfunc = (Math.exp(SZF * f) - 1.0) / (XKF * SZF * fc);
                df = -func / dfunc;
                f += df;
                if (Math.abs(df) < e)
                    break;
                if (i == 20) {
                    System.out.println("Max number of iterations exceeded\n");
//                    throw new Exception("Max number of iterations exceeded");
                }
            }
            if (f < (cumf + rint * (it + 1) * timeInterval)) {
                df = f - cumf;
                cumf = f;
            }
        }
        EXPResult.put("df", df);
        EXPResult.put("cumf", cumf);
        return EXPResult;
    }

    /**
     * 计算分级河道汇流时间、分级河道汇流滞后时段、产流量在各滞后时段内到达出口断面的比例（参考C语言与Fortran代码版本）
     */
    private void init_flow() {

        TCH = new double[NCH];

        RVDT = rv * timeInterval;  // 坡面汇流速度*时间DT
        CHVDT = chv * timeInterval;// 河道汇流速度*时间DT

        TCH[0] = D[0] / CHVDT; // 河道汇流时段数
        for (int i = 1; i < NCH; i++) {
            TCH[i] = TCH[0] + (D[i] - D[0]) / RVDT;// 河道汇流时段数+坡面汇流时段数
        }

        NR = (int) (TCH[NCH - 1]);    // 最远河道滞后时段
        if ((float) (NR) < (TCH[NCH - 1]))
            NR++;
        ND = (int) (TCH[0]);        // 最近河道滞后时段
        if ((float) (ND) < (TCH[0]))
            ND++;
        NRD = NR - ND;

        ARate = new double[NRD];
        qb0DTInitials = new double[NR];

        for (int IR = 0; IR < NRD; IR++) {// 地表坡面汇流时段循环
            if (ND + IR + 1 >= TCH[NCH - 1])    // 从最近点时段开始
                ARate[IR] = 1.0;        // 若大于最远点滞时时间，则为比例为1.0
            else {
                for (int i = 1; i < NCH; i++) {
                    if (ND + IR + 1 < TCH[i]) {
                        ARate[IR] = (ACH[i - 1] +
                                (ACH[i] - ACH[i - 1]) * ((ND + IR + 1) - TCH[i - 1]) / (TCH[i] - TCH[i - 1])) / Area;
                        break;
                    }
                }
            }
        }

        /*源代码中有AREA，本代码版本不涉及子流域，故舍去，即AREA=1.0*/
        ARateData = new double[ARate.length];

        if (ARateData.length > 0) {
            ARateData[0] = ARate[0];
            if (NR > 1) {
                for (int j = 1; j < NRD; j++) {
                    ARateData[j] = ARate[j] - ARate[j - 1];
                }
            }
        }

        /*初始流量（壤中流）设置，ND段相等、ND~NR-1段逐渐下降*/
        for (int i = 0; i < ND; i++) {
            qb0DTInitials[i] = qb0DTInitial;
        }

        for (int i = 0; i < NRD; i++) {
            qb0DTInitials[ND + i] = qb0DTInitial * (1 - ARate[i]);
        }
    }

    /**
     * 蒸发能力计算
     *
     * @param date   降水时间
     * @param timeIn 时间间隔 (h)
     * @return 蒸发能力
     */

    private double calcEvaporationPotential(Date date, double timeIn) {
        Calendar time = Calendar.getInstance();
        time.setTime(date);
        Integer Month = time.get(Calendar.MONTH) + 1; // 获得降雨开始月份
        double[] Ev = new double[3]; // 根据月份确定该时刻小雨、中雨、大雨的蒸发能力;

        //        if (Month == 4)
        //            Ev = Eall[0];
        //        else if (Month == 5)
        //            Ev = Eall[1];
        //        else if (Month == 6)
        //            Ev = Eall[2];
        //        else if (Month == 7)
        //            Ev = Eall[3];
        //        else if (Month == 8)
        //            Ev = Eall[4];
        //        else if (Month == 9)
        //            Ev = Eall[5];
        //        else if (Month == 10)
        //            Ev = Eall[6];
        //        else
        //            System.out.println("The Evaporation of some MONTHs is not found.");
        //
        //        rain = rain * 24 / timeIn;  //时段降雨量转换成日降雨量
        //
        //        double[] Ms = calcRainMembership(rain); // 计算该场降雨对小雨、中雨、大雨的隶属度
        //
        double Ep = ES[Month - 1];
        //        for (int i = 0; i < Ms.length; i++) { // 隶属度和蒸发数组加权求和
        //            Ep += Ev[i] * Ms[i];
        //        }
        Ep = Ep * timeIn / 24; // 日蒸发量转换成时段蒸发量
        return Ep;
    }

    /**
     * 对降雨量的隶属度计算
     *
     * @param rain 降水量
     * @return 降雨对小雨、中雨、大雨的隶属度
     */

    public double[] calcRainMembership(double rain) {
        double[] Pms = {5.0, 17.5, 30.0};

        double[] Ms = new double[Pms.length]; // 该时段降雨对小、中、大雨的隶属度

        if (rain <= Pms[0]) {
            Ms[0] = 1.0; // 对小雨的隶属度
            Ms[1] = 0.0; // 对中雨的隶属度
            Ms[2] = 0.0; // 对大雨的隶属度
        } else if (rain > Pms[0] && rain <= Pms[1]) {
            Ms[0] = (Pms[1] - rain) / (Pms[1] - Pms[0]);
            Ms[1] = (rain - Pms[0]) / (Pms[1] - Pms[0]);
            Ms[2] = 0.0;
        } else if (rain > Pms[1] && rain <= Pms[2]) {
            Ms[0] = 0.0;
            Ms[1] = (Pms[2] - rain) / (Pms[2] - Pms[1]);
            Ms[2] = (rain - Pms[1]) / (Pms[2] - Pms[1]);
        } else {
            Ms[0] = 0.0;
            Ms[1] = 0.0;
            Ms[2] = 1.0;
        }

        return Ms;
    }

    /**
     * 汇流计算
     *
     * @return 流量过程
     */

    private void topmodel_flow() {

        double U = Area /
                (3.6 * timeInterval); //R 单位转换系数（km2/h = 1000000 m2/ 3600 s = 1000m2/3.6s，km2·mm/h = 1000000 * 0.001 m3/
        // 3600 s = m3/3.6s）
        int IN = 0;

        for (int i = 0; i < NR; i++) {
            if (i < floodRainRange) {
                Q[i] = qb0DTInitials[i];
                QB[i] = qb0DTInitials[i];
                QS[i] = 0.0;
            }
        }

        for (int IT = 0; IT < floodRainRange; IT++) {
            for (int IR = 0; IR < NRD; IR++) {
                IN = IT + ND + IR;
                if (IN < floodRainRange) {
                    QB[IN] = QB[IN] + RB[IT] * ARateData[IR] * U;
                    QS[IN] = QS[IN] + RS[IT] * ARateData[IR] * U;
                    Q[IN] = Q[IN] + RunoffSim[IT] * ARateData[IR] * U;
                }
            }
        }
    }

    private List<String> toStringList(double[] array0) {
        String[] array = new String[array0.length];
        for (int i = 0; i < array.length; i++) {
            array[i] = String.valueOf(array0[i]);
        }
        return Arrays.asList(array);
    }

    private List<String> toStringList(double[][] array0) {
        String[] array = new String[array0.length];
        for (int i = 0; i < array.length; i++) {
            array[i] = Arrays.toString(array0[i]);
        }
        return Arrays.asList(array);
    }

    @Override
    public void init() {

    }

    @SneakyThrows
    @Override
    public PredictResult predict() {
        PredictResult result = new PredictResult();
        Map<String, double[]> map = new HashMap<>();
        try {
            map = TOPMODEL();
        } catch (Exception e) {
            // 处理异常
        }
        double[][] RSim = new double[6][];
        RSim[0] = map.get("RS");
        RSim[1] = map.get("RB");
        RSim[2] = map.get("RunoffSim");
        RSim[3] = map.get("QS");
        RSim[4] = map.get("QB");
        RSim[5] = map.get("QSim");

        result.setRunoffSim(map.get("RunoffSim"));
        result.setRSim(RSim);
        result.setQSim(map.get("QSim"));

        // 更新状态
        List<String> SRZ0 = toStringList(Srz0);
        List<String> SUZ0 = toStringList(Suz0);
        List<String> QB0 = toStringList(rb0Initials);

        Map<String, List<String>> status = new HashMap<>();
        //根系区点缺水量
        status.put("SRZ0", SRZ0);
        //非饱和层点含水量
        status.put("SUZ0", SUZ0);
        //时段初壤中流
        status.put("QB0", QB0);

        result.setNewStatus(status);

        return result;
    }

    public int getHours(Date dt_beg, Date dt_end) {
        int hours = -1;
        hours = Long.valueOf((dt_end.getTime() - dt_beg.getTime()) / (3600 * 1000L)).intValue();
        return hours;
    }

    public static void main(String[] args) {
        String a = "{\"RV\":\"3600\",\"D\":\"[120.710347582, 310.121967417, 587.345394803, 623.053550055]\",\"F\":\"66191.4073888\",\"SZM\":\"0.02\",\"L\":\"623.05354963791\",\"N\":\"4\",\"SU0\":\"[0.0, 0.0, 0.0]\",\"CHV\":\"7000\",\"dt\":\"[\\\"2010-06-17 08:00:00\\\",\\\"2010-06-17 14:00:00\\\",\\\"2010-06-17 20:00:00\\\",\\\"2010-06-18 02:00:00\\\",\\\"2010-06-18 08:00:00\\\",\\\"2010-06-18 14:00:00\\\",\\\"2010-06-18 20:00:00\\\",\\\"2010-06-19 02:00:00\\\",\\\"2010-06-19 08:00:00\\\",\\\"2010-06-19 14:00:00\\\",\\\"2010-06-19 20:00:00\\\",\\\"2010-06-20 02:00:00\\\",\\\"2010-06-20 08:00:00\\\",\\\"2010-06-20 14:00:00\\\",\\\"2010-06-20 20:00:00\\\",\\\"2010-06-21 02:00:00\\\",\\\"2010-06-21 08:00:00\\\",\\\"2010-06-21 14:00:00\\\",\\\"2010-06-21 20:00:00\\\",\\\"2010-06-22 02:00:00\\\",\\\"2010-06-22 08:00:00\\\",\\\"2010-06-22 14:00:00\\\",\\\"2010-06-22 20:00:00\\\",\\\"2010-06-23 02:00:00\\\",\\\"2010-06-23 08:00:00\\\",\\\"2010-06-23 14:00:00\\\",\\\"2010-06-23 20:00:00\\\",\\\"2010-06-24 02:00:00\\\",\\\"2010-06-24 08:00:00\\\",\\\"2010-06-24 14:00:00\\\",\\\"2010-06-24 20:00:00\\\",\\\"2010-06-25 02:00:00\\\",\\\"2010-06-25 08:00:00\\\",\\\"2010-06-25 14:00:00\\\",\\\"2010-06-25 20:00:00\\\",\\\"2010-06-26 02:00:00\\\",\\\"2010-06-26 08:00:00\\\",\\\"2010-06-26 14:00:00\\\",\\\"2010-06-26 20:00:00\\\",\\\"2010-06-27 02:00:00\\\",\\\"2010-06-27 08:00:00\\\",\\\"2010-06-27 14:00:00\\\",\\\"2010-06-27 20:00:00\\\",\\\"2010-06-28 02:00:00\\\",\\\"2010-06-28 08:00:00\\\",\\\"2010-06-28 14:00:00\\\",\\\"2010-06-28 20:00:00\\\",\\\"2010-06-29 02:00:00\\\",\\\"2010-06-29 08:00:00\\\",\\\"2010-06-29 14:00:00\\\",\\\"2010-06-29 20:00:00\\\",\\\"2010-06-30 02:00:00\\\",\\\"2010-06-30 08:00:00\\\",\\\"2010-06-30 14:00:00\\\",\\\"2010-06-30 20:00:00\\\",\\\"2010-07-01 02:00:00\\\",\\\"2010-07-01 08:00:00\\\",\\\"2010-07-01 14:00:00\\\",\\\"2010-07-01 20:00:00\\\",\\\"2010-07-02 02:00:00\\\",\\\"2010-07-02 08:00:00\\\",\\\"2010-07-02 14:00:00\\\",\\\"2010-07-02 20:00:00\\\",\\\"2010-07-03 02:00:00\\\",\\\"2010-07-03 08:00:00\\\",\\\"2010-07-03 14:00:00\\\",\\\"2010-07-03 20:00:00\\\",\\\"2010-07-04 02:00:00\\\",\\\"2010-07-04 08:00:00\\\",\\\"2010-07-04 14:00:00\\\",\\\"2010-07-04 20:00:00\\\",\\\"2010-07-05 02:00:00\\\",\\\"2010-07-05 08:00:00\\\",\\\"2010-07-05 14:00:00\\\",\\\"2010-07-05 20:00:00\\\",\\\"2010-07-06 02:00:00\\\",\\\"2010-07-06 08:00:00\\\",\\\"2010-07-06 14:00:00\\\",\\\"2010-07-06 20:00:00\\\",\\\"2010-07-07 02:00:00\\\",\\\"2010-07-07 08:00:00\\\",\\\"2010-07-07 14:00:00\\\",\\\"2010-07-07 20:00:00\\\",\\\"2010-07-08 02:00:00\\\",\\\"2010-07-08 08:00:00\\\",\\\"2010-07-08 14:00:00\\\",\\\"2010-07-08 20:00:00\\\",\\\"2010-07-09 02:00:00\\\",\\\"2010-07-09 08:00:00\\\",\\\"2010-07-09 14:00:00\\\",\\\"2010-07-09 20:00:00\\\",\\\"2010-07-10 02:00:00\\\",\\\"2010-07-10 08:00:00\\\",\\\"2010-07-10 14:00:00\\\",\\\"2010-07-10 20:00:00\\\",\\\"2010-07-11 02:00:00\\\",\\\"2010-07-11 08:00:00\\\",\\\"2010-07-11 14:00:00\\\",\\\"2010-07-11 20:00:00\\\",\\\"2010-07-12 02:00:00\\\",\\\"2010-07-12 08:00:00\\\",\\\"2010-07-12 14:00:00\\\",\\\"2010-07-12 20:00:00\\\",\\\"2010-07-13 02:00:00\\\",\\\"2010-07-13 08:00:00\\\",\\\"2010-07-13 14:00:00\\\",\\\"2010-07-13 20:00:00\\\",\\\"2010-07-14 02:00:00\\\",\\\"2010-07-14 08:00:00\\\",\\\"2010-07-14 14:00:00\\\",\\\"2010-07-14 20:00:00\\\",\\\"2010-07-15 02:00:00\\\",\\\"2010-07-15 08:00:00\\\",\\\"2010-07-15 14:00:00\\\",\\\"2010-07-15 20:00:00\\\",\\\"2010-07-16 02:00:00\\\",\\\"2010-07-16 08:00:00\\\",\\\"2010-07-16 14:00:00\\\",\\\"2010-07-16 20:00:00\\\",\\\"2010-07-17 02:00:00\\\",\\\"2010-07-17 08:00:00\\\",\\\"2010-07-17 14:00:00\\\",\\\"2010-07-17 20:00:00\\\",\\\"2010-07-18 02:00:00\\\",\\\"2010-07-18 08:00:00\\\",\\\"2010-07-18 14:00:00\\\",\\\"2010-07-18 20:00:00\\\",\\\"2010-07-19 02:00:00\\\",\\\"2010-07-19 08:00:00\\\",\\\"2010-07-19 14:00:00\\\",\\\"2010-07-19 20:00:00\\\",\\\"2010-07-20 02:00:00\\\",\\\"2010-07-20 08:00:00\\\",\\\"2010-07-20 14:00:00\\\",\\\"2010-07-20 20:00:00\\\",\\\"2010-07-21 02:00:00\\\",\\\"2010-07-21 08:00:00\\\",\\\"2010-07-21 14:00:00\\\",\\\"2010-07-21 20:00:00\\\",\\\"2010-07-22 02:00:00\\\",\\\"2010-07-22 08:00:00\\\",\\\"2010-07-22 14:00:00\\\",\\\"2010-07-22 20:00:00\\\",\\\"2010-07-23 02:00:00\\\",\\\"2010-07-23 08:00:00\\\",\\\"2010-07-23 14:00:00\\\",\\\"2010-07-23 20:00:00\\\",\\\"2010-07-24 02:00:00\\\",\\\"2010-07-24 08:00:00\\\",\\\"2010-07-24 14:00:00\\\",\\\"2010-07-24 20:00:00\\\",\\\"2010-07-25 02:00:00\\\",\\\"2010-07-25 08:00:00\\\",\\\"2010-07-25 14:00:00\\\",\\\"2010-07-25 20:00:00\\\",\\\"2010-07-26 02:00:00\\\",\\\"2010-07-26 08:00:00\\\",\\\"2010-07-26 14:00:00\\\",\\\"2010-07-26 20:00:00\\\",\\\"2010-07-27 02:00:00\\\",\\\"2010-07-27 08:00:00\\\",\\\"2010-07-27 14:00:00\\\",\\\"2010-07-27 20:00:00\\\",\\\"2010-07-28 02:00:00\\\",\\\"2010-07-28 08:00:00\\\",\\\"2010-07-28 14:00:00\\\",\\\"2010-07-28 20:00:00\\\",\\\"2010-07-29 02:00:00\\\",\\\"2010-07-29 08:00:00\\\",\\\"2010-07-29 14:00:00\\\",\\\"2010-07-29 20:00:00\\\",\\\"2010-07-30 02:00:00\\\",\\\"2010-07-30 08:00:00\\\",\\\"2010-07-30 14:00:00\\\",\\\"2010-07-30 20:00:00\\\",\\\"2010-07-31 02:00:00\\\",\\\"2010-07-31 08:00:00\\\",\\\"2010-07-31 14:00:00\\\",\\\"2010-07-31 20:00:00\\\",\\\"2010-08-01 02:00:00\\\",\\\"2010-08-01 08:00:00\\\",\\\"2010-08-01 14:00:00\\\",\\\"2010-08-01 20:00:00\\\",\\\"2010-08-02 02:00:00\\\",\\\"2010-08-02 08:00:00\\\",\\\"2010-08-02 14:00:00\\\",\\\"2010-08-02 20:00:00\\\",\\\"2010-08-03 02:00:00\\\",\\\"2010-08-03 08:00:00\\\",\\\"2010-08-03 14:00:00\\\",\\\"2010-08-03 20:00:00\\\",\\\"2010-08-04 02:00:00\\\",\\\"2010-08-04 08:00:00\\\",\\\"2010-08-04 14:00:00\\\",\\\"2010-08-04 20:00:00\\\",\\\"2010-08-05 02:00:00\\\",\\\"2010-08-05 08:00:00\\\",\\\"2010-08-05 14:00:00\\\",\\\"2010-08-05 20:00:00\\\",\\\"2010-08-06 02:00:00\\\",\\\"2010-08-06 08:00:00\\\",\\\"2010-08-06 14:00:00\\\",\\\"2010-08-06 20:00:00\\\",\\\"2010-08-07 02:00:00\\\",\\\"2010-08-07 08:00:00\\\",\\\"2010-08-07 14:00:00\\\",\\\"2010-08-07 20:00:00\\\",\\\"2010-08-08 02:00:00\\\",\\\"2010-08-08 08:00:00\\\",\\\"2010-08-08 14:00:00\\\",\\\"2010-08-08 20:00:00\\\",\\\"2010-08-09 02:00:00\\\",\\\"2010-08-09 08:00:00\\\",\\\"2010-08-09 14:00:00\\\",\\\"2010-08-09 20:00:00\\\",\\\"2010-08-10 02:00:00\\\",\\\"2010-08-10 08:00:00\\\",\\\"2010-08-10 14:00:00\\\",\\\"2010-08-10 20:00:00\\\",\\\"2010-08-11 02:00:00\\\",\\\"2010-08-11 08:00:00\\\",\\\"2010-08-11 14:00:00\\\",\\\"2010-08-11 20:00:00\\\",\\\"2010-08-12 02:00:00\\\",\\\"2010-08-12 08:00:00\\\",\\\"2010-08-12 14:00:00\\\",\\\"2010-08-12 20:00:00\\\",\\\"2010-08-13 02:00:00\\\",\\\"2010-08-13 08:00:00\\\",\\\"2010-08-13 14:00:00\\\",\\\"2010-08-13 20:00:00\\\",\\\"2010-08-14 02:00:00\\\",\\\"2010-08-14 08:00:00\\\",\\\"2010-08-14 14:00:00\\\",\\\"2010-08-14 20:00:00\\\",\\\"2010-08-15 02:00:00\\\",\\\"2010-08-15 08:00:00\\\",\\\"2010-08-15 14:00:00\\\",\\\"2010-08-15 20:00:00\\\",\\\"2010-08-16 02:00:00\\\",\\\"2010-08-16 08:00:00\\\",\\\"2020-06-17 08:00:00\\\",\\\"2020-06-17 14:00:00\\\",\\\"2020-06-17 20:00:00\\\",\\\"2020-06-18 02:00:00\\\",\\\"2020-06-18 08:00:00\\\",\\\"2020-06-18 14:00:00\\\",\\\"2020-06-18 20:00:00\\\",\\\"2020-06-19 02:00:00\\\",\\\"2020-06-19 08:00:00\\\",\\\"2020-06-19 14:00:00\\\",\\\"2020-06-19 20:00:00\\\",\\\"2020-06-20 02:00:00\\\",\\\"2020-06-20 08:00:00\\\",\\\"2020-06-20 14:00:00\\\",\\\"2020-06-20 20:00:00\\\",\\\"2020-06-21 02:00:00\\\",\\\"2020-06-21 08:00:00\\\",\\\"2020-06-21 14:00:00\\\",\\\"2020-06-21 20:00:00\\\",\\\"2020-06-22 02:00:00\\\",\\\"2020-06-22 08:00:00\\\",\\\"2020-06-22 14:00:00\\\",\\\"2020-06-22 20:00:00\\\",\\\"2020-06-23 02:00:00\\\",\\\"2020-06-23 08:00:00\\\",\\\"2020-06-23 14:00:00\\\",\\\"2020-06-23 20:00:00\\\",\\\"2020-06-24 02:00:00\\\",\\\"2020-06-24 08:00:00\\\",\\\"2020-06-24 14:00:00\\\",\\\"2020-06-24 20:00:00\\\",\\\"2020-06-25 02:00:00\\\",\\\"2020-06-25 08:00:00\\\",\\\"2020-06-25 14:00:00\\\",\\\"2020-06-25 20:00:00\\\",\\\"2020-06-26 02:00:00\\\",\\\"2020-06-26 08:00:00\\\",\\\"2020-06-26 14:00:00\\\",\\\"2020-06-26 20:00:00\\\",\\\"2020-06-27 02:00:00\\\",\\\"2020-06-27 08:00:00\\\",\\\"2020-06-27 14:00:00\\\",\\\"2020-06-27 20:00:00\\\",\\\"2020-06-28 02:00:00\\\",\\\"2020-06-28 08:00:00\\\",\\\"2020-06-28 14:00:00\\\",\\\"2020-06-28 20:00:00\\\",\\\"2020-06-29 02:00:00\\\",\\\"2020-06-29 08:00:00\\\",\\\"2020-06-29 14:00:00\\\",\\\"2020-06-29 20:00:00\\\",\\\"2020-06-30 02:00:00\\\",\\\"2020-06-30 08:00:00\\\",\\\"2020-06-30 14:00:00\\\",\\\"2020-06-30 20:00:00\\\",\\\"2020-07-01 02:00:00\\\",\\\"2020-07-01 08:00:00\\\",\\\"2020-07-01 14:00:00\\\",\\\"2020-07-01 20:00:00\\\",\\\"2020-07-02 02:00:00\\\",\\\"2020-07-02 08:00:00\\\",\\\"2020-07-02 14:00:00\\\",\\\"2020-07-02 20:00:00\\\",\\\"2020-07-03 02:00:00\\\",\\\"2020-07-03 08:00:00\\\",\\\"2020-07-03 14:00:00\\\",\\\"2020-07-03 20:00:00\\\",\\\"2020-07-04 02:00:00\\\",\\\"2020-07-04 08:00:00\\\",\\\"2020-07-04 14:00:00\\\",\\\"2020-07-04 20:00:00\\\",\\\"2020-07-05 02:00:00\\\",\\\"2020-07-05 08:00:00\\\",\\\"2020-07-05 14:00:00\\\",\\\"2020-07-05 20:00:00\\\",\\\"2020-07-06 02:00:00\\\",\\\"2020-07-06 08:00:00\\\",\\\"2020-07-06 14:00:00\\\",\\\"2020-07-06 20:00:00\\\",\\\"2020-07-07 02:00:00\\\",\\\"2020-07-07 08:00:00\\\",\\\"2020-07-07 14:00:00\\\",\\\"2020-07-07 20:00:00\\\",\\\"2020-07-08 02:00:00\\\",\\\"2020-07-08 08:00:00\\\",\\\"2020-07-08 14:00:00\\\",\\\"2020-07-08 20:00:00\\\",\\\"2020-07-09 02:00:00\\\",\\\"2020-07-09 08:00:00\\\",\\\"2020-07-09 14:00:00\\\",\\\"2020-07-09 20:00:00\\\",\\\"2020-07-10 02:00:00\\\",\\\"2020-07-10 08:00:00\\\",\\\"2020-07-10 14:00:00\\\",\\\"2020-07-10 20:00:00\\\",\\\"2020-07-11 02:00:00\\\",\\\"2020-07-11 08:00:00\\\",\\\"2020-07-11 14:00:00\\\",\\\"2020-07-11 20:00:00\\\",\\\"2020-07-12 02:00:00\\\",\\\"2020-07-12 08:00:00\\\",\\\"2020-07-12 14:00:00\\\",\\\"2020-07-12 20:00:00\\\",\\\"2020-07-13 02:00:00\\\",\\\"2020-07-13 08:00:00\\\",\\\"2020-07-13 14:00:00\\\",\\\"2020-07-13 20:00:00\\\",\\\"2020-07-14 02:00:00\\\",\\\"2020-07-14 08:00:00\\\",\\\"2020-07-14 14:00:00\\\",\\\"2020-07-14 20:00:00\\\",\\\"2020-07-15 02:00:00\\\",\\\"2020-07-15 08:00:00\\\",\\\"2020-07-15 14:00:00\\\",\\\"2020-07-15 20:00:00\\\",\\\"2020-07-16 02:00:00\\\",\\\"2020-07-16 08:00:00\\\",\\\"2020-07-16 14:00:00\\\",\\\"2020-07-16 20:00:00\\\",\\\"2020-07-17 02:00:00\\\",\\\"2020-07-17 08:00:00\\\",\\\"2020-07-17 14:00:00\\\",\\\"2020-07-17 20:00:00\\\",\\\"2020-07-18 02:00:00\\\",\\\"2020-07-18 08:00:00\\\",\\\"2020-07-18 14:00:00\\\",\\\"2020-07-18 20:00:00\\\",\\\"2020-07-19 02:00:00\\\",\\\"2020-07-19 08:00:00\\\",\\\"2020-07-19 14:00:00\\\",\\\"2020-07-19 20:00:00\\\",\\\"2020-07-20 02:00:00\\\",\\\"2020-07-20 08:00:00\\\",\\\"2020-07-20 14:00:00\\\",\\\"2020-07-20 20:00:00\\\",\\\"2020-07-21 02:00:00\\\",\\\"2020-07-21 08:00:00\\\",\\\"2020-07-21 14:00:00\\\",\\\"2020-07-21 20:00:00\\\",\\\"2020-07-22 02:00:00\\\",\\\"2020-07-22 08:00:00\\\",\\\"2020-07-22 14:00:00\\\",\\\"2020-07-22 20:00:00\\\",\\\"2020-07-23 02:00:00\\\",\\\"2020-07-23 08:00:00\\\",\\\"2020-07-23 14:00:00\\\",\\\"2020-07-23 20:00:00\\\",\\\"2020-07-24 02:00:00\\\",\\\"2020-07-24 08:00:00\\\",\\\"2020-07-24 14:00:00\\\",\\\"2020-07-24 20:00:00\\\",\\\"2020-07-25 02:00:00\\\",\\\"2020-07-25 08:00:00\\\",\\\"2020-07-25 14:00:00\\\",\\\"2020-07-25 20:00:00\\\",\\\"2020-07-26 02:00:00\\\",\\\"2020-07-26 08:00:00\\\",\\\"2020-07-26 14:00:00\\\",\\\"2020-07-26 20:00:00\\\",\\\"2020-07-27 02:00:00\\\",\\\"2020-07-27 08:00:00\\\",\\\"2020-07-27 14:00:00\\\",\\\"2020-07-27 20:00:00\\\",\\\"2020-07-28 02:00:00\\\",\\\"2020-07-28 08:00:00\\\",\\\"2020-07-28 14:00:00\\\",\\\"2020-07-28 20:00:00\\\",\\\"2020-07-29 02:00:00\\\",\\\"2020-07-29 08:00:00\\\",\\\"2020-07-29 14:00:00\\\",\\\"2020-07-29 20:00:00\\\",\\\"2020-07-30 02:00:00\\\",\\\"2020-07-30 08:00:00\\\",\\\"2020-07-30 14:00:00\\\",\\\"2020-07-30 20:00:00\\\",\\\"2020-07-31 02:00:00\\\",\\\"2020-07-31 08:00:00\\\",\\\"2020-07-31 14:00:00\\\",\\\"2020-07-31 20:00:00\\\",\\\"2020-08-01 02:00:00\\\",\\\"2020-08-01 08:00:00\\\",\\\"2020-08-01 14:00:00\\\",\\\"2020-08-01 20:00:00\\\",\\\"2020-08-02 02:00:00\\\",\\\"2020-08-02 08:00:00\\\",\\\"2020-08-02 14:00:00\\\",\\\"2020-08-02 20:00:00\\\",\\\"2020-08-03 02:00:00\\\",\\\"2020-08-03 08:00:00\\\",\\\"2020-08-03 14:00:00\\\",\\\"2020-08-03 20:00:00\\\",\\\"2020-08-04 02:00:00\\\",\\\"2020-08-04 08:00:00\\\",\\\"2020-08-04 14:00:00\\\",\\\"2020-08-04 20:00:00\\\",\\\"2020-08-05 02:00:00\\\",\\\"2020-08-05 08:00:00\\\",\\\"2020-08-05 14:00:00\\\",\\\"2020-08-05 20:00:00\\\",\\\"2020-08-06 02:00:00\\\",\\\"2020-08-06 08:00:00\\\",\\\"2020-08-06 14:00:00\\\",\\\"2020-08-06 20:00:00\\\",\\\"2020-08-07 02:00:00\\\",\\\"2020-08-07 08:00:00\\\",\\\"2020-08-07 14:00:00\\\",\\\"2020-08-07 20:00:00\\\",\\\"2020-08-08 02:00:00\\\",\\\"2020-08-08 08:00:00\\\",\\\"2020-08-08 14:00:00\\\",\\\"2020-08-08 20:00:00\\\",\\\"2020-08-09 02:00:00\\\",\\\"2020-08-09 08:00:00\\\",\\\"2020-08-09 14:00:00\\\",\\\"2020-08-09 20:00:00\\\",\\\"2020-08-10 02:00:00\\\",\\\"2020-08-10 08:00:00\\\",\\\"2020-08-10 14:00:00\\\",\\\"2020-08-10 20:00:00\\\",\\\"2020-08-11 02:00:00\\\",\\\"2020-08-11 08:00:00\\\",\\\"2020-08-11 14:00:00\\\",\\\"2020-08-11 20:00:00\\\",\\\"2020-08-12 02:00:00\\\",\\\"2020-08-12 08:00:00\\\",\\\"2020-08-12 14:00:00\\\",\\\"2020-08-12 20:00:00\\\",\\\"2020-08-13 02:00:00\\\",\\\"2020-08-13 08:00:00\\\",\\\"2020-08-13 14:00:00\\\",\\\"2020-08-13 20:00:00\\\",\\\"2020-08-14 02:00:00\\\",\\\"2020-08-14 08:00:00\\\",\\\"2020-08-14 14:00:00\\\",\\\"2020-08-14 20:00:00\\\",\\\"2020-08-15 02:00:00\\\",\\\"2020-08-15 08:00:00\\\",\\\"2020-08-15 14:00:00\\\",\\\"2020-08-15 20:00:00\\\",\\\"2020-08-16 02:00:00\\\",\\\"2020-08-16 08:00:00\\\",\\\"2021-05-05 20:00:00\\\",\\\"2021-05-06 02:00:00\\\",\\\"2021-05-06 08:00:00\\\",\\\"2021-05-06 14:00:00\\\",\\\"2021-05-06 20:00:00\\\",\\\"2021-05-07 02:00:00\\\",\\\"2021-05-07 08:00:00\\\",\\\"2021-05-07 14:00:00\\\",\\\"2021-05-07 20:00:00\\\",\\\"2021-05-08 02:00:00\\\",\\\"2021-05-08 08:00:00\\\",\\\"2021-05-08 14:00:00\\\",\\\"2021-05-08 20:00:00\\\",\\\"2021-05-09 02:00:00\\\",\\\"2021-05-09 08:00:00\\\",\\\"2021-05-09 14:00:00\\\",\\\"2021-05-09 20:00:00\\\",\\\"2021-05-10 02:00:00\\\",\\\"2021-05-10 08:00:00\\\",\\\"2021-05-10 14:00:00\\\",\\\"2021-05-10 20:00:00\\\",\\\"2021-05-11 02:00:00\\\",\\\"2021-05-11 08:00:00\\\",\\\"2021-05-11 14:00:00\\\",\\\"2021-05-11 20:00:00\\\",\\\"2021-05-12 02:00:00\\\",\\\"2021-05-12 08:00:00\\\",\\\"2021-05-12 14:00:00\\\",\\\"2021-05-12 20:00:00\\\",\\\"2021-05-13 02:00:00\\\",\\\"2021-05-13 08:00:00\\\",\\\"2021-05-13 14:00:00\\\",\\\"2021-05-13 20:00:00\\\",\\\"2021-05-14 02:00:00\\\",\\\"2021-05-14 08:00:00\\\",\\\"2021-05-14 14:00:00\\\",\\\"2021-05-14 20:00:00\\\",\\\"2021-05-15 02:00:00\\\",\\\"2021-05-15 08:00:00\\\",\\\"2021-05-15 14:00:00\\\",\\\"2021-05-15 20:00:00\\\",\\\"2021-05-16 02:00:00\\\",\\\"2021-05-16 08:00:00\\\",\\\"2021-05-16 14:00:00\\\",\\\"2021-05-16 20:00:00\\\",\\\"2021-05-17 02:00:00\\\",\\\"2021-05-17 08:00:00\\\",\\\"2021-05-17 14:00:00\\\",\\\"2021-05-17 20:00:00\\\",\\\"2021-05-18 02:00:00\\\",\\\"2021-05-18 08:00:00\\\",\\\"2021-05-18 14:00:00\\\",\\\"2021-05-18 20:00:00\\\",\\\"2021-05-19 02:00:00\\\",\\\"2021-05-19 08:00:00\\\",\\\"2021-05-19 14:00:00\\\",\\\"2021-05-19 20:00:00\\\",\\\"2021-05-20 02:00:00\\\",\\\"2021-05-20 08:00:00\\\",\\\"2021-05-20 14:00:00\\\",\\\"2021-05-20 20:00:00\\\",\\\"2021-05-21 02:00:00\\\",\\\"2021-05-21 08:00:00\\\",\\\"2021-05-21 14:00:00\\\",\\\"2021-05-21 20:00:00\\\",\\\"2021-05-22 02:00:00\\\",\\\"2021-05-22 08:00:00\\\",\\\"2021-05-22 14:00:00\\\",\\\"2021-05-22 20:00:00\\\",\\\"2021-05-23 02:00:00\\\",\\\"2021-05-23 08:00:00\\\",\\\"2021-05-23 14:00:00\\\",\\\"2021-05-23 20:00:00\\\",\\\"2021-05-24 02:00:00\\\",\\\"2021-05-24 08:00:00\\\",\\\"2021-05-24 14:00:00\\\",\\\"2021-05-24 20:00:00\\\",\\\"2021-05-25 02:00:00\\\",\\\"2021-05-25 08:00:00\\\",\\\"2021-05-25 14:00:00\\\",\\\"2021-05-25 20:00:00\\\",\\\"2021-05-26 02:00:00\\\",\\\"2021-05-26 08:00:00\\\",\\\"2021-05-26 14:00:00\\\",\\\"2021-05-26 20:00:00\\\",\\\"2021-05-27 02:00:00\\\",\\\"2021-05-27 08:00:00\\\",\\\"2021-05-27 14:00:00\\\",\\\"2021-05-27 20:00:00\\\",\\\"2021-05-28 02:00:00\\\",\\\"2021-05-28 08:00:00\\\",\\\"2021-05-28 14:00:00\\\",\\\"2021-05-28 20:00:00\\\",\\\"2021-05-29 02:00:00\\\",\\\"2021-05-29 08:00:00\\\",\\\"2021-05-29 14:00:00\\\",\\\"2021-05-29 20:00:00\\\",\\\"2021-05-30 02:00:00\\\",\\\"2021-05-30 08:00:00\\\",\\\"2021-05-30 14:00:00\\\",\\\"2021-05-30 20:00:00\\\",\\\"2021-05-31 02:00:00\\\",\\\"2021-05-31 08:00:00\\\",\\\"2021-05-31 14:00:00\\\",\\\"2021-05-31 20:00:00\\\",\\\"2021-06-01 02:00:00\\\",\\\"2021-06-01 08:00:00\\\",\\\"2021-06-01 14:00:00\\\",\\\"2021-06-01 20:00:00\\\",\\\"2021-06-02 02:00:00\\\",\\\"2021-06-02 08:00:00\\\",\\\"2021-06-02 14:00:00\\\",\\\"2021-06-02 20:00:00\\\",\\\"2021-06-03 02:00:00\\\",\\\"2021-06-03 08:00:00\\\",\\\"2021-06-03 14:00:00\\\",\\\"2021-06-03 20:00:00\\\",\\\"2021-06-04 02:00:00\\\",\\\"2021-06-04 08:00:00\\\",\\\"2021-06-04 14:00:00\\\",\\\"2021-06-04 20:00:00\\\",\\\"2021-06-05 02:00:00\\\",\\\"2021-06-05 08:00:00\\\",\\\"2021-06-05 14:00:00\\\",\\\"2021-06-05 20:00:00\\\",\\\"2021-06-06 02:00:00\\\",\\\"2021-06-06 08:00:00\\\",\\\"2021-06-06 14:00:00\\\",\\\"2021-06-06 20:00:00\\\",\\\"2021-06-07 02:00:00\\\",\\\"2021-06-07 08:00:00\\\",\\\"2021-06-07 14:00:00\\\",\\\"2021-06-07 20:00:00\\\",\\\"2021-06-08 02:00:00\\\",\\\"2021-06-08 08:00:00\\\",\\\"2021-06-08 14:00:00\\\",\\\"2021-06-08 20:00:00\\\",\\\"2021-06-09 02:00:00\\\",\\\"2021-06-09 08:00:00\\\",\\\"2021-06-09 14:00:00\\\",\\\"2021-06-09 20:00:00\\\",\\\"2021-06-10 02:00:00\\\",\\\"2021-06-10 08:00:00\\\",\\\"2021-06-10 14:00:00\\\",\\\"2021-06-10 20:00:00\\\",\\\"2021-06-11 02:00:00\\\",\\\"2021-06-11 08:00:00\\\",\\\"2021-06-11 14:00:00\\\",\\\"2021-06-11 20:00:00\\\",\\\"2021-06-12 02:00:00\\\",\\\"2021-06-12 08:00:00\\\",\\\"2021-06-12 14:00:00\\\",\\\"2021-06-12 20:00:00\\\",\\\"2021-06-13 02:00:00\\\",\\\"2021-06-13 08:00:00\\\",\\\"2021-06-13 14:00:00\\\",\\\"2021-06-13 20:00:00\\\",\\\"2021-06-14 02:00:00\\\",\\\"2021-06-14 08:00:00\\\",\\\"2021-06-14 14:00:00\\\",\\\"2021-06-14 20:00:00\\\",\\\"2021-06-15 02:00:00\\\",\\\"2021-06-15 08:00:00\\\",\\\"2021-06-15 14:00:00\\\",\\\"2021-06-15 20:00:00\\\",\\\"2021-06-16 02:00:00\\\",\\\"2021-06-16 08:00:00\\\",\\\"2021-06-16 14:00:00\\\",\\\"2021-06-16 20:00:00\\\",\\\"2021-06-17 02:00:00\\\",\\\"2021-06-17 08:00:00\\\",\\\"2021-06-17 14:00:00\\\",\\\"2021-06-17 20:00:00\\\",\\\"2021-06-18 02:00:00\\\",\\\"2021-06-18 08:00:00\\\",\\\"2021-06-18 14:00:00\\\",\\\"2021-06-18 20:00:00\\\",\\\"2021-06-19 02:00:00\\\",\\\"2021-06-19 08:00:00\\\",\\\"2021-06-19 14:00:00\\\",\\\"2021-06-19 20:00:00\\\",\\\"2021-06-20 02:00:00\\\",\\\"2021-06-20 08:00:00\\\",\\\"2021-06-20 14:00:00\\\",\\\"2021-06-20 20:00:00\\\",\\\"2021-06-21 02:00:00\\\",\\\"2021-06-21 08:00:00\\\",\\\"2021-06-21 14:00:00\\\",\\\"2021-06-21 20:00:00\\\",\\\"2021-06-22 02:00:00\\\",\\\"2021-06-22 08:00:00\\\",\\\"2021-06-22 14:00:00\\\",\\\"2021-06-22 20:00:00\\\",\\\"2021-06-23 02:00:00\\\",\\\"2021-06-23 08:00:00\\\",\\\"2021-06-23 14:00:00\\\",\\\"2021-06-23 20:00:00\\\",\\\"2021-06-24 02:00:00\\\",\\\"2021-06-24 08:00:00\\\",\\\"2021-06-24 14:00:00\\\",\\\"2021-06-24 20:00:00\\\",\\\"2021-06-25 02:00:00\\\",\\\"2021-06-25 08:00:00\\\",\\\"2021-06-25 14:00:00\\\",\\\"2021-06-25 20:00:00\\\",\\\"2021-06-26 02:00:00\\\",\\\"2021-06-26 08:00:00\\\",\\\"2021-06-26 14:00:00\\\",\\\"2021-06-26 20:00:00\\\",\\\"2021-06-27 02:00:00\\\",\\\"2021-06-27 08:00:00\\\",\\\"2021-06-27 14:00:00\\\",\\\"2021-06-27 20:00:00\\\",\\\"2021-06-28 02:00:00\\\",\\\"2021-06-28 08:00:00\\\",\\\"2021-06-28 14:00:00\\\",\\\"2021-06-28 20:00:00\\\",\\\"2021-06-29 02:00:00\\\",\\\"2021-06-29 08:00:00\\\",\\\"2021-06-29 14:00:00\\\",\\\"2021-06-29 20:00:00\\\",\\\"2021-06-30 02:00:00\\\",\\\"2021-06-30 08:00:00\\\",\\\"2021-06-30 14:00:00\\\",\\\"2021-06-30 20:00:00\\\",\\\"2021-07-01 02:00:00\\\",\\\"2021-07-01 08:00:00\\\",\\\"2021-07-01 14:00:00\\\",\\\"2021-07-01 20:00:00\\\",\\\"2021-07-02 02:00:00\\\",\\\"2021-07-02 08:00:00\\\",\\\"2021-07-02 14:00:00\\\",\\\"2021-07-02 20:00:00\\\",\\\"2021-07-03 02:00:00\\\",\\\"2021-07-03 08:00:00\\\",\\\"2021-07-03 14:00:00\\\",\\\"2021-07-03 20:00:00\\\",\\\"2021-07-04 02:00:00\\\",\\\"2021-07-04 08:00:00\\\",\\\"2021-07-04 14:00:00\\\",\\\"2021-07-04 20:00:00\\\",\\\"2021-07-05 02:00:00\\\",\\\"2021-07-05 08:00:00\\\",\\\"2021-07-05 14:00:00\\\",\\\"2021-07-05 20:00:00\\\",\\\"2021-07-06 02:00:00\\\",\\\"2021-07-06 08:00:00\\\"]\",\"T0\":\"0.15\",\"XK0\":\"13.2\",\"INFEX\":\"1\",\"ST\":\"[26.2180671692, 25.0825481415, 23.9486808777, 22.8162403107, 21.6836109161, 20.5506763458, 19.4176063538, 18.2850055695, 17.1521320343, 16.0194091797, 14.8867082596, 13.7540597916, 12.6212291718, 11.4885091782, 10.3557748795, 9.2231836319, 8.09038257599, 6.95761013031, 5.82499837875, 4.6921415329]\",\"rain\":\"[0.175,0.2030303,0.23030303,0.23030303,0.2030303,0.22916666666666666,0.22916666666666666,0.5625,0.3958333333333333,0.054545449999999995,0.054545449999999995,0.3090909,0.08181818,0.342028985,0.040579706666666666,0.008695651666666665,0.008695651666666665,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.5333333333333333,0.5333333333333333,0.5333333333333333,0.5333333333333333,0.26666666666666666,0.26666666666666666,0.26666666666666666,0.26666666666666666,0.3125,0.3125,0.3125,0.3125,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.375,0.875,0.375,0.375,0.041666666666666664,0.041666666666666664,0.041666666666666664,0.041666666666666664,0.0,0.0,0.0,0.0,0.24642857166666665,0.6305555666666667,2.7099207858333334,0.24642857166666665,1.1916666666666664,0.024999999999999998,0.19166666666666665,0.024999999999999998,2.18190895,7.275641216666666,6.627492866666666,1.3816239333333333,0.008333333333333333,0.008333333333333333,0.008333333333333333,0.008333333333333333,0.0,0.09999999999999999,0.0,0.0,0.0,0.5,0.0,0.0,0.0,0.0,0.0,0.0,0.041666666666666664,0.041666666666666664,0.041666666666666664,0.041666666666666664,0.6916666666666667,0.6916666666666667,0.6916666666666667,1.6916666666666667,2.8666666666666663,0.16666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.15869565166666666,0.18091787833333334,1.3016907333333332,0.3253623183333333,2.89,7.306666666666666,6.619999999999999,5.149999523333332,0.016666666666666666,0.3833333333333333,0.3833333333333333,0.016666666666666666,1.747368425,12.510526299999999,0.02105263166666667,0.02105263166666667,0.0,0.0,0.0,0.0,0.11666666666666665,0.016666666666666666,0.016666666666666666,0.016666666666666666,12.399999999999999,7.833333333333332,2.833333333333333,2.6666666666666665,0.07075098833333333,0.8210805333333332,0.07075098833333333,0.07075098833333333,0.06086956333333333,1.2507248199999998,0.06086956333333333,0.06086956333333333,0.0,0.0,0.0,0.0,0.5242424,0.03636363333333333,0.03636363333333333,0.03636363333333333,0.09824561166666666,0.09824561166666666,3.5099415,2.8935671,0.0,0.0,0.0,0.03333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.24390645333333333,0.24390645333333333,0.24390645333333333,1.9016139166666668,1.624016583333333,0.0364389225,0.0364389225,0.0364389225,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.27857143,1.5071428333333332,1.3404762,0.8404761933333333,1.9394444166666664,8.964444499999999,0.7266666666666666,0.9361111166666666,1.3236841666666666,0.260526315,0.260526315,4.288596500000001,6.373333166666667,6.6911111666666665,2.9555555166666667,2.913333333333333,0.5333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.29791655,0.26666666666666666,1.0166666666666666,0.5854166999999999,1.39537038,17.590741166666668,3.5027777799999997,0.9444444466666666,0.024999999999999998,0.6916666666666667,0.49166666666666664,0.058333333333333334,0.03333333333333333,0.36666666666666664,0.03333333333333333,0.03333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.9446078516666666,1.34656865,5.595588166666666,3.2799019166666663,2.83073595,0.16753246333333333,0.16753246333333333,0.16753246333333333,0.0037267039875780003,0.0,0.0,0.0,0.0,0.018877532122449,0.018877532122449,0.090306032122449,1.4433659280612,0.0,0.0,0.0,5.742851400000001,0.50101991755101,11.029070542347,0.84387671897958,0.15459168540816004,0.0714285,0.142857,0.0,0.0,0.0,0.0,0.0,0.0,1.003570425,1.5642841500000002,0.8857134142857,0.289285425,0.03571425,0.03571425,0.03571425,0.03571425,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.8833440652254803,4.9625619374331,1.24048770808248,0.08502665497326001,0.0,0.0,0.0,0.0,0.41055858944100004,0.02981363304348,0.02981363304348,0.02981363304348,0.39999960000000007,0.25714260000000005,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.21428550000000002,0.0,0.0,0.0,0.0714285,0.0,0.0,0.0038960996753250004,0.08961029967532501,0.17402579740260002,0.0038960996753250004,0.024999975,2.1821408178570003,0.024999975,0.082142775,2.6178544821429,0.01785712500000007,0.01785712500000007,0.01785712500000007,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,19.628551800000004,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.1952379047619,0.8777769365079001,5.8174543396827,0.2666664047619,0.00952380047619,9.844434441270002,0.03650790206349001,0.08095230047619001,0.0,0.0,0.0,0.0,0.39285675000000003,0.67857075,12.74998725,7.7357068357140015,16.271411585715,0.02857140000000004,0.02857140000000004,0.02857140000000004,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.8571389571429,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,7.916225855194801,6.973369635194821,0.17662320051948008,0.3623373005194801,1.25510080918365,1.25510080918365,10.188425311564501,1.12993089149655,0.00745340826087,0.00745340826087,5.193162508260871,2.8347797366460004,0.7028250657456601,23.204686366719002,54.477967236264,18.571566714129002,1.3515292670408101,0.28010176704081,1.1855430430272,6.182817174319499,1.1422066435065001,2.1512964344157,0.7538953318182,4.395450318831,0.47142810000000007,0.014285700000000002,0.014285700000000002,0.014285700000000002,0.010714275,0.12499987500000001,0.296428275,0.039285675000000006,0.0714285,0.4714281,0.0428571,0.0999999,1.2285702,2.5142832285714,0.285714,0.0,13.0714155,9.29046761523738,0.49047570095238,0.04761900095238,0.0,0.142857,0.0,0.0,0.0714285,0.22857120000000003,0.0999999,0.0714285,0.0,0.0,0.0,0.0,0.5425504797346921,0.6139789797346921,4.808396620170001,5.220777064932,0.35714250000000003,0.0428571,0.0428571,0.0428571,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.014285700000000002,0.014285700000000002,0.014285700000000002,0.014285700000000002,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.014285700000000002,0.014285700000000002,0.32857110000000006,0.12857130000000003,0.5372175056391,0.08759389669173001,0.05902249669173,0.05902249669173,0.0,0.0,0.37142820000000004,0.7428564000000001,0.568876982122449,2.5076505637755004,0.197448782122449,0.16887738212244902,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.42499958928570003,0.13928557500000002,0.05357137500000001,0.05357137500000001,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0714285,0.0999999,0.1999998,0.0,0.0,0.0714285,0.32142825,0.37857105,0.02142855,0.02142855,0.3285711,0.0714285,0.0714285,0.0714285,1.0999989142857,0.028571400000000004,0.0,0.0,0.0,0.0,0.0,0.0,0.12857130000000003,0.19999980000000003,0.12857130000000003,0.12857130000000003,0.07857135000000001,0.22142835000000002,0.007142850000000001,0.07857135000000001,0.0,0.21428550000000002,0.0,0.0,0.08155453987395,0.08155453987395,0.7978983878151,2.4389891895798,8.428563,0.285714,0.285714,0.285714,0.010714275,0.010714275,0.11071417500000001,1.9678551750000002,8.852669861607001,2.4151762133928,0.3732139125,0.05892851250000011,4.232138625,2.132140725,8.874991125,0.5321423250000001,0.031676991180120004,0.0037267039875780003,0.0037267039875780003,0.0037267039875780003,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.117857025,0.117857025,0.117857025,2.874997125,0.21428550000000002,0.0,0.0,0.0,0.0,0.0,0.142857,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.028571400000000004,0.0,0.0,0.0,0.0,0.396428175,0.5392851750000001,5.582137275,1.9392838035714002,2.5178545678572,1.2892844250000004,0.103571325,0.13214272500000002,0.3749996250000001,0.6607136250000001,1.2464273250000002,7.017850125,0.0,0.0,0.0,0.0,0.2571426,2.3142834142857,8.371420157142902,4.0142817142857,0.7428564000000001,3.3285681142857,0.285714,0.0,0.0,0.0,0.0,0.05714280000000001,0.0,1.6428555,0.0,0.0,0.028571400000000004,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.35714250000000003,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.4892852250000002,0.5607137250000003,5.532137382142801,6.317850825,0.25714260000000005,0.0,1.4714270571429,0.8999991,0.339285375,4.6964238892857,1.267855875,0.6821421892857,3.4785679500000004,6.07856535,0.22142835000000002,0.19285695000000003,0.07499992500000001,1.7892839250000003,1.274998725,0.817856325]\",\"AC\":\"[0.00345902777501, 0.00130138888785, 0.00132986111005, 0.00126874999899, 0.00669791666131, 0.0193847222067, 0.0240562499808, 0.0324583333074, 0.045581944408, 0.0616652777284, 0.096886805478, 0.116340972129, 0.181878472077, 0.296451388652, 0.564480555104, 1.12570833243, 1.91927222069, 2.33020069258, 1.36739166557, 0.122974305457]\",\"ACH\":\"[44568.932268, 59582.570036, 61371.8553499, 66191.4073888]\",\"start\":\"\\\"2010-07-17 08:00:00\\\"\",\"ES\":\"[23.8, 23.2, 33.7, 53, 66.6, 78.9, 122.3, 113.9, 90.8, 62.9, 46.2, 34.1]\",\"SR0\":\"[0.0, 0.0, 0.0]\",\"TD\":\"3\",\"q\":\"[]\",\"runoffSim\":\"[]\",\"DTH\":\"0.35\",\"clen\":\"6\",\"SRMAX\":\"0.03\",\"QB0\":\"0.0\",\"HF\":\"0.06\"}";
        Map data = JSON.parseObject(a, Map.class);
        TOPE obj = new TOPE(data);
        PredictResult result = obj.predict();
        double[] runoff = result.getRunoffSim();//径流
        double[] rs = result.getRSim()[0];//坡面流
        double[] rb = result.getRSim()[1];//壤中流
        System.out.println("坡面流: ");
        for(int i=0; i<obj.floodRainRange; i++) {
            System.out.print(rs[i] + " ");
        }
        System.out.println();
        System.out.println("壤中流: ");
        for(int i=0; i<obj.floodRainRange; i++) {
            System.out.print(rb[i] + " ");
        }
        System.out.println();
        System.out.println("径流: ");
        for(int i=0; i<obj.floodRainRange; i++) {
            System.out.print(runoff[i] + " ");
        }
//        System.out.println(obj.predict());
    }
}